import socket
import struct
import sys
from Crypto.Cipher import AES
from Crypto.Hash import MD5
import binascii
import array

#"2.6.190.56","2.6.190.63","33996344","33996351","GB","United Kingdom"


def ip2netOrderInt(ip):
    #print 'ip : ', ip
    netorder = struct.unpack("i", socket.inet_aton(ip))[0]
    #print netorder
    if netorder > 0:
        #print "net order int : ", netorder
        pass
    else:
        temp = netorder
        netorder += 4294967296
    return netorder

def nint2ip(ip):

    ip = int(ip)
    origin_ip = ip
    if ip < 0:
            ip += 4294967296

    #hostip = struct.unpack("I", socket.inet_aton(ip))[0]
    netip = ip


    return socket.inet_ntoa(struct.pack('I', netip))

def nint2hint(ip):
    #print '----------input must be net order----------'
    ip = int(ip)
    origin_ip = ip
    if ip < 0:
            ip += 4294967296

    #hostip = struct.unpack("I", socket.inet_aton(ip))[0]
    netip = ip

    if origin_ip < 0:
        pass
            #print 'net order = ', origin_ip, '  ', ip
    else:
        pass
            #print 'net order = ', origin_ip

    #print "net order = ",netip
    hostip = socket.ntohl(netip)

    print 'ip : ', socket.inet_ntoa(struct.pack('I', netip))

    #print "host_order = ",hostip
    origin_hostip = hostip
    if hostip < 0:
               hostip += 4294967296;

    if origin_hostip <0:
            print 'host order = ', origin_hostip, '  ', hostip
    else:
            print 'host order = ', origin_hostip



def encrypt(needEncryStr, passwd):
    obj = AES.new(passwd)
    tmpstr = needEncryStr
    out = ''
    blockSize = AES.block_size

 #   print 'blockSize = ', blockSize

 #   print  binascii.b2a_hex(tmpstr)

    while len(tmpstr) >= blockSize:

        innerStr = tmpstr[:blockSize]
        #print binascii.b2a_hex(innerStr)
        out += obj.encrypt(innerStr)
        tmpstr = tmpstr[blockSize:]

    a = blockSize - len(tmpstr)
    tmparray = array.array('B')

    for i in range(a):
        tmparray.append(a)
    tmpstr += tmparray.tostring()

    #print binascii.b2a_hex(tmpstr)

    out += obj.encrypt(tmpstr)

    #print 'out = ' , binascii.b2a_hex(out)

    return out

def encrypt_md5(needEncryStr, passwd):

    m = MD5.new()
    m.update(passwd)
    passwd = m.digest()

    obj = AES.new(passwd)
    tmpstr = needEncryStr
    out = ''
    blockSize = AES.block_size

 #   print 'blockSize = ', blockSize

 #   print  binascii.b2a_hex(tmpstr)

    while len(tmpstr) >= blockSize:

        innerStr = tmpstr[:blockSize]
        #print binascii.b2a_hex(innerStr)
        out += obj.encrypt(innerStr)
        tmpstr = tmpstr[blockSize:]

    a = blockSize - len(tmpstr)
    tmparray = array.array('B')

    for i in range(a):
        tmparray.append(a)
    tmpstr += tmparray.tostring()

    #print binascii.b2a_hex(tmpstr)

    out += obj.encrypt(tmpstr)

    #print 'out = ' , binascii.b2a_hex(out)

    return out



def decrypt(needDecryptStr, passwd):
    obj = AES.new(passwd)
    tmpstr = needDecryptStr
    out = ''
    blockSize = AES.block_size

    while len(tmpstr) > 0:
        innerStr = tmpstr[:blockSize]
        out += obj.decrypt(innerStr)
        tmpstr = tmpstr[blockSize:]

    return out

def decrypt_md5(needDecryptStr, passwd):

    m = MD5.new()
    m.update(passwd)
    passwd = m.digest()
    
    obj = AES.new(passwd)
    tmpstr = needDecryptStr
    out = ''
    blockSize = AES.block_size

    while len(tmpstr) > 0:
        innerStr = tmpstr[:blockSize]
        out += obj.decrypt(innerStr)
        tmpstr = tmpstr[blockSize:]

    return out

def getInt(input = ['','']):
    reInt = struct.unpack_from('I', input[0], input[1])[0]
    input[1] += 4
    return reInt

def getByte(input = ['','']):
    reInt = struct.unpack_from('B', input[0], input[1])[0]
    input[1] += 1
    return reInt

def getShort(input = ['','']):
    reInt = struct.unpack_from('H', input[0], input[1])[0]
    input[1] += 2
    return reInt

def getString(input = ['', '']):
    strlen = struct.unpack_from('I', input[0], input[1])[0]
    input[1] += 4
    realstr = struct.unpack_from('%ds'%strlen, input[0], input[1])[0]
    input[1] += strlen
    return realstr


def put64(input =['',''], value = 123):
    struct.pack_into('Q', input[0], input[1], value)
    input[1] += 8

def putInt(input =['',''], value = 123):
    struct.pack_into('I', input[0], input[1], value)
    input[1] += 4
    
def putByte(input =['',''], value = 12):
    struct.pack_into('B', input[0], input[1], value)
    input[1] += 1

def putShort(input =['',''], value = 12):
    struct.pack_into('H', input[0], input[1], value)
    input[1] += 2
    
def putString(input =['',''], value = 'qyf'):
    strlen = len(value)
    struct.pack_into('I', input[0], input[1], strlen)
    input[1] += 4
    struct.pack_into('%ds'%strlen, input[0], input[1], value)
    input[1] += strlen
    


#################################################################

################################################################################
def net_oreder_put64(input =['',''], value = 123):
    #vastr = struct.pack('Q', value)
    #value = struct.unpack('!Q',vastr)
    struct.pack_into('!Q', input[0], input[1], value)
    input[1] += 8

def net_oreder_putInt(input =['',''], value = 123):
    struct.pack_into('!I', input[0], input[1], value)
    input[1] += 4
    
def net_oreder_putByte(input =['',''], value = 12):
    struct.pack_into('B', input[0], input[1], value)
    input[1] += 1

def net_oreder_putShort(input =['',''], value = 12):
    struct.pack_into('!H', input[0], input[1], value)
    input[1] += 2

def net_oreder_putString(input =['',''], value = 'qyf'):
    strlen = len(value)
    struct.pack_into('!H', input[0], input[1], strlen)
    input[1] += 2
    struct.pack_into('%ds'%(len(value)), input[0], input[1], value)
    input[1] += len(value)

def net_oreder_putLongString(input =['',''], value = 'qyf'):
    strlen = len(value)
    struct.pack_into('!I', input[0], input[1], strlen)
    input[1] += 4
    struct.pack_into('%ds'%(len(value)), input[0], input[1], value)
    input[1] += len(value)
    
    
    ################################
def netOrder_getInt(input = ['','']):
    reInt = struct.unpack_from('!I', input[0], input[1])[0]
    input[1] += 4
    return reInt

def netOrder_getByte(input = ['','']):
    reInt = struct.unpack_from('B', input[0], input[1])[0]
    input[1] += 1
    return reInt

def netOrder_getShort(input = ['','']):
    reInt = struct.unpack_from('!H', input[0], input[1])[0]
    input[1] += 2
    return reInt

def netOrder_get64(input = ['','']):
    reInt = struct.unpack_from('!Q', input[0], input[1])[0]
    input[1] += 8
    return reInt

def netOrder_getString(input = ['', '']):
    strlen = struct.unpack_from('!I', input[0], input[1])[0]
    input[1] += 4
    realstr = struct.unpack_from('%ds'%strlen, input[0], input[1])[0]
    input[1] += strlen
    return realstr


